/* 
    先来让我们看看什么是Operator
        当操作符被调用时，它们不会改变已经存在的 Observable 实例。相反，它们返回一个新的 Observable ，它的 subscription 逻辑基于第一个 Observable
        注意： 每次被调用，会返回一个全新的 Observable
*/
// 像是map, filter, contactAll... 等等，所有这些函式都会拿到原本的observable 并回传一个新的observable，就像有点像下面这个样子
// take, first, takeUntil, concatAll 这四个operators
// let people = Rx.Observable.of('Jerry', 'Anna');

// function map(source, callback) {
//     return Rx.Observable.create((observer) => {
//         return source.subscribe(
//             (value) => { 
//                 try{
//                     observer.next(callback(value));
//                 } catch(e) {
//                     observer.error(e);
//                 }
//             },
//             (err) => { observer.error(err); },
//             () => { observer.complete() }
//         )
//     })
// }

// let helloPeople = map(people, (item) => item + ' Hello~');

// helloPeople.subscribe(console.log);

/* 
    takeUntil
    在实务上takeUntil 很常使用到，他可以在某件事情发生时，让一个observable 直送出完成(complete)讯息，范例如下
*/
let sourceTakeUntil = Rx.Observable.interval(1000);
let clickTakeUntil = Rx.Observable.fromEvent(document.body, 'click');
let exampleTakeUntil = sourceTakeUntil.takeUntil(clickTakeUntil);     
   
exampleTakeUntil.subscribe({
    next: (value) => { console.log(value); },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});

/* 
    concatAll 把二维数组转换成一维数组
    这里需要注意的是 concatAll 会处理source 先发出来的observable，
    必须等到这个observable 结束，才会再处理下一个source 发出来的observable，
*/
// let obs1 = Rx.Observable.interval(1000).take(5);
// let obs2 = Rx.Observable.interval(500).take(2);
// let obs3 = Rx.Observable.interval(2000).take(1);
// // obs1.subscribe(console.log)
// let sourceConcatAll = Rx.Observable.of(obs1, obs2, obs3);

// let exampleConcatAll = sourceConcatAll.concatAll();

// exampleConcatAll.subscribe({
//     next: (value) => { console.log(value, 'next'); },
//     error: (err) => { console.log('Error: ' + err); },
//     complete: () => { console.log('complete'); }
// });
let sourceT = Rx.Observable.interval(1000).take(3);
var source2 = Rx.Observable.of(3)
var source3 = Rx.Observable.of(4,5,6)
var example = sourceT.concat(source2, source3);

example.subscribe({
    next: (value) => { 
        console.log(value);
        console.log(value + '1');
    },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});

/* 
     take 可以取前几个送出的元素，今天介绍可以略过前几个送出元素的
*/